package com.insta.playdroid;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.insta.playdroid.metier.domain.Song;
import com.insta.utils.HeadsetConnectionReceiver;
import com.insta.utils.SingletonPlayer;

public class PlayerActivity extends Activity {

	private Button buttonPlayStop;
	private Button buttonPrev;
	private Button buttonNext;
	private ToggleButton tbuttonRepeatAll;
	private ToggleButton tbuttonRepeatOne;
	private ToggleButton tbuttonRandom;
	private TextView tvInfoMediaArtiste;
	private TextView tvInfoMediaTitre;
	private TextView tvInfoMediaAlbum;
	private ImageView imJackette;
	private MediaPlayer mediaPlayer = SingletonPlayer.getInstancePlayer();
	private SeekBar seekBar;
	private Song song = new Song();
	private boolean flagNextOrPrevSong = false;
	public static final String ON = "ON";
	public static final String OFF = "OFF";
	private final Handler handler = new Handler();
	// private boolean repeatOne = false;
	// private boolean repeatAll = false;
	// private boolean random = false;
	private List<Integer> lastRandomIndexSong = new ArrayList<Integer>();
	// private List<Song> songs;
	// int codeList;

	IPlayer player;
	private BroadcastReceiver headsetReceiver;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.player);

		player = PlayerFactory.getPlayer();
		if (player.getSong() != null) {
			song = player.getSong();
		} else {
			song = new Song();
		}

		/* creating and registering intent receiver */
		headsetReceiver = new HeadsetConnectionReceiver();
		registerReceiver(headsetReceiver, new IntentFilter(
				Intent.ACTION_HEADSET_PLUG));

		TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

		tm.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);

		// Planifier une action à la fin de la lecture du fichier.
		mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
			public void onCompletion(MediaPlayer mediaPlayerParam) {

				buttonPlayStop.setTag(false);
				buttonClickNext();

			}
		});

		if (mediaPlayer.isPlaying() && player.isCallfromMenu()) {
			reloadVue();
		} else {
			jouer();
		}

	}

	private void jouer() {
		try {
			// init la vue
			initViews();
			// afficher les infos de la song
			updateInfoMusic();
			// lancer la music
			lauchMusic();
			// init la seekBar
			playMedia();
			// lancer la seekBar
			startPlayProgressUpdater();

		} catch (IllegalArgumentException e) {
			Log.d("erreur oncreate", e.getMessage());
		} catch (IllegalStateException e) {
			Log.d("erreur oncreate", e.getMessage());
		} catch (IOException e) {
			Log.d("erreur oncreate", e.getMessage());
		}
	}

	/**
	 * Ecoute l'état des appels émis et sortants afin de gérer le player
	 */
	private PhoneStateListener mPhoneListener = new PhoneStateListener()

	{
		public void onCallStateChanged(int state, String incomingNumber)

		{
			switch (state)

			{
			case TelephonyManager.CALL_STATE_RINGING:

			{
				if (mediaPlayer.isPlaying())
					mediaPlayer.pause();

				Log.v("CALL_STATE_RINGING", "Ringing");

			}

				break;

			case TelephonyManager.CALL_STATE_OFFHOOK:

			{
				if (mediaPlayer.isPlaying())
					mediaPlayer.pause();
				Log.v("CALL_STATE_OFFHOOK", "OffHook");
			}

				break;

			case TelephonyManager.CALL_STATE_IDLE:

			{
				if (!mediaPlayer.isPlaying())
					mediaPlayer.start();

				Log.v("CALL_STATE_IDLE", "Idle(No activity)");
			}
				break;

			default:

				Log.d("TAG", "Unknown phone state=" + state);

			}

		}

	};

	// This method set the setOnClickListener and method for it (buttonClick())
	private void initViews() throws IllegalArgumentException,
			IllegalStateException, IOException {
		// chargement des boutons
		buttonPlayStop = (Button) findViewById(R.id.button_play_stop);
		buttonPlayStop.setTag(false);
		buttonPrev = (Button) findViewById(R.id.button_prev);
		buttonNext = (Button) findViewById(R.id.button_next);
		tbuttonRepeatOne = (ToggleButton) findViewById(R.id.tbutton_repeat_one);
		tbuttonRepeatAll = (ToggleButton) findViewById(R.id.tbutton_repeat_all);
		tbuttonRandom = (ToggleButton) findViewById(R.id.tbutton_aleatoire);
		tvInfoMediaArtiste = (TextView) findViewById(R.id.tv_info_artist);
		tvInfoMediaTitre = (TextView) findViewById(R.id.tv_info_titre);
		tvInfoMediaAlbum = (TextView) findViewById(R.id.tv_info_album);
		imJackette = (ImageView) findViewById(R.id.jackette);

		int largeurPixel = getResources().getDisplayMetrics().widthPixels;
		imJackette.setAdjustViewBounds(true);
		imJackette.setLayoutParams(new LayoutParams(largeurPixel / 2,
				largeurPixel / 2));
		// ajout des listeners sur les boutons
		buttonPlayStop.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				buttonClick();
			}
		});
		buttonPrev.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				buttonClickPrev();
			}
		});
		buttonNext.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				buttonClickNext();
			}
		});
		tbuttonRepeatOne.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				buttonClickRepeatOne();
			}
		});
		tbuttonRepeatAll.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				buttonClickRepeatAll();
			}
		});
		tbuttonRandom.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				buttonClickRandom();
			}
		});
	}

	/**
	 * update titre, jacket,... du son joué
	 */
	public void updateInfoMusic() {
		tvInfoMediaTitre.setText(song.getTitle());
		tvInfoMediaArtiste.setText(song.getArtist());
		tvInfoMediaAlbum.setText(song.getAlbum());
		// jackette
		if (song.getImage() != null) {
			imJackette.setImageURI(song.getImage());
		} else {
			imJackette.setBackgroundResource(R.drawable.albumart);
		}
	}

	/**
	 * demander de jouer la musique
	 * 
	 * @param songPath
	 * @throws IOException
	 */
	private void lauchMusic() throws IOException {
		player.play();
		buttonPlayStop.setBackgroundResource(R.drawable.pause_player_icone);
	}

	/**
	 * init SeekBar
	 * 
	 * @param songPath
	 * @throws IOException
	 */
	private void playMedia() throws IOException {

		seekBar = (SeekBar) findViewById(R.id.seekbar01);
		seekBar.setMax(mediaPlayer.getDuration());
		seekBar.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				seekChange(v);

				// seekBar.postDelayed();
				return false;
			}
		});

		if (flagNextOrPrevSong) {
			// démarrer la lecture de la piste précédente/suivante
			playNextOrPreviousSong();
		} else {
			// démarer/pause
			buttonClick();
		}
	}

	public void startPlayProgressUpdater() {
		seekBar.setProgress(mediaPlayer.getCurrentPosition());

		// // passe au média suivant quand celui en cours est fini
		// if (seekBar.getProgress() == mediaPlayer.getDuration()) {
		// buttonClickNext();
		// }

		// gestion play/pause
		if (mediaPlayer.isPlaying()) {
			Runnable notification = new Runnable() {
				public void run() {
					startPlayProgressUpdater();
				}
			};
			handler.postDelayed(notification, 1000);
		} else {
			mediaPlayer.pause();
			// buttonPlayStop.setText(getString(R.string.play_str));
			buttonPlayStop.setBackgroundResource(R.drawable.play_player_icone);
			buttonPlayStop.setTag(false);
			seekBar.setProgress(0);
		}
	}

	// This is event handler thumb moving event
	private void seekChange(View v) {
		if (mediaPlayer.isPlaying()) {
			SeekBar sb = (SeekBar) v;
			mediaPlayer.seekTo(sb.getProgress());
		}
	}

	// This is event handler for buttonClick event
	private void buttonClick() {
		// if (buttonPlayStop.getText() == getString(R.string.play_str)) {
		// buttonPlayStop.setText(getString(R.string.pause_str));

		if (buttonPlayStop.getTag().equals(false)) {
			buttonPlayStop.setBackgroundResource(R.drawable.pause_player_icone);
			buttonPlayStop.setTag(true);
			try {
				mediaPlayer.start();
				startPlayProgressUpdater();
			} catch (IllegalStateException e) {
				Log.d("MediaPlayer", "exception to start in buttonClick");
				mediaPlayer.pause();
			}
		} else {
			// buttonPlayStop.setText(getString(R.string.play_str));
			buttonPlayStop.setBackgroundResource(R.drawable.play_player_icone);
			buttonPlayStop.setTag(false);
			mediaPlayer.pause();
		}
	}

	/**
	 * lire la chanson suivante ou précédente
	 */
	private void playNextOrPreviousSong() {

		// if (buttonPlayStop.getText() == getString(R.string.play_str)) {
		// buttonPlayStop.setText(getString(R.string.pause_str));
		// }
		if (buttonPlayStop.getTag().equals(false)) {
			buttonPlayStop.setBackgroundResource(R.drawable.pause_player_icone);
			buttonPlayStop.setTag(true);
		}

		mediaPlayer.start();
		startPlayProgressUpdater();
		flagNextOrPrevSong = false;
	}

	/**
	 * lance le média précédent le courant
	 */
	private void buttonClickPrev() {
		Song s = player.prevSong();
		if (s != null) {
			song = s;
			jouer();
		} else {
			Toast.makeText(this, R.string.errorNoPrevSong, Toast.LENGTH_SHORT)
					.show();
		}

	}

	/**
	 * lance le média suivant le courant
	 */
	private void buttonClickNext() {
		Song s = player.nextSong();
		if (s != null) {
			song = s;
			jouer();
		} else {
			Toast.makeText(this, R.string.errorNoNextSong, Toast.LENGTH_SHORT)
					.show();
		}
	}

	/**
	 * répète (boucle sur) tous les médias de la liste
	 */
	private void buttonClickRepeatOne() {

		if (tbuttonRepeatOne.isChecked()) {
			player.setRepeatOne(true);
			player.setRepeatAll(false);
			tbuttonRepeatOne
					.setBackgroundResource(R.drawable.repeat_one_off_red);
			tbuttonRepeatAll.setChecked(false);
			tbuttonRepeatAll
					.setBackgroundResource(R.drawable.repeat_control_icone);
		} else {
			player.setRepeatOne(false);
			tbuttonRepeatOne
					.setBackgroundResource(R.drawable.repeat_one_on__green);
		}

	}

	/**
	 * répète le média en cours de lecture
	 */
	private void buttonClickRepeatAll() {
		Log.d("Tbutton", String.valueOf(tbuttonRepeatAll.getTextOn()));
		if (tbuttonRepeatAll.isChecked()) {
			player.setRepeatAll(true);
			tbuttonRepeatAll.setBackgroundResource(R.drawable.repeat_order);
			player.setRepeatOne(false);
			tbuttonRepeatOne.setChecked(false);
			tbuttonRepeatOne
					.setBackgroundResource(R.drawable.repeat_one_on__green);
		} else {
			player.setRepeatAll(false);
			tbuttonRepeatAll
					.setBackgroundResource(R.drawable.repeat_control_icone);
		}
	}

	/**
	 * lire les médias aléatoirement
	 */
	private void buttonClickRandom() {
		if (tbuttonRandom.isChecked()) {
			player.setRandom(true);
			tbuttonRandom.setBackgroundResource(R.drawable.shuffle_on);
			lastRandomIndexSong.removeAll(lastRandomIndexSong);
		} else {
			player.setRandom(false);
			tbuttonRandom.setBackgroundResource(R.drawable.shuffle_off);
		}
	}

	/* unregistering intent receiver */
	public void onDestroy() {
		super.onDestroy();
		unregisterReceiver(headsetReceiver);
		mPhoneListener = null;
	}

	/**
	 * la vue est créer avec une chanson en cours
	 */
	public void reloadVue() {
		if (mediaPlayer.isPlaying()) {

			// init la vue
			try {
				initViews();
				// afficher les infos de la song
				updateInfoMusic();
				// init la seekBar
				playMedia();
				// lancer la seekBar
				startPlayProgressUpdater();
				// update etat bouton play
				buttonPlayStop
						.setBackgroundResource(R.drawable.pause_player_icone);

				// //update seekBar progress
				// seekBar.setProgress(mediaPlayer.getCurrentPosition());
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalStateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	@Override
	public void onBackPressed() {
		player.setCallfromMenu(false);

		super.onBackPressed();
	}
}